#ifndef OPENHITLS_KAE_DGST_H
#define OPENHITLS_KAE_DGST_H

#include <bsl_params.h>
#include <crypt_algid.h>

#include <wd.h>
#include <wd_digest.h>

#include <stdint.h>

#define SM3_BLOCK_NUM    4
#define SM3_DIGEST_SIZE  32

#define MD5_BLOCK_NUM    4
#define MD5_DIGEST_SIZE  16

#define SHA1_BLOCK_NUM    4
#define SHA1_DIGEST_SIZE  20

#define SHA256_BLOCK_NUM    4
#define SHA256_DIGEST_SIZE  32

#define SHA224_BLOCK_NUM    4
#define SHA224_DIGEST_SIZE  28

#define SHA384_BLOCK_NUM    8
#define SHA384_DIGEST_SIZE  48

#define SHA512_BLOCK_NUM    8
#define SHA512_DIGEST_SIZE  64

#define SHA512_224_BLOCK_NUM    8
#define SHA512_224_DIGEST_SIZE  28

#define SHA512_256_BLOCK_NUM    8
#define SHA512_256_DIGEST_SIZE  32

#define DGST_BLOCK_SIZE  (512 * 1024)
#define DGST_CACHE_SIZE  1024

#define KAE_REQ

typedef struct KAE_DGST_Ctx
{
    struct wd_queue                     queue;
    struct wd_queue_mempool*            pool;
    struct wcrypto_digest_ctx_setup     setup;
    struct wcrypto_digest_op_data       opData;

    CRYPT_MD_AlgId                      id;
    uint8_t                             block[DGST_CACHE_SIZE];
    void*                               digestCtx;
    uint32_t                            digestSize;
    uint32_t                            remain;
} KAE_DGST_Ctx;

KAE_DGST_Ctx* KAE_DGST_NewCtx(CRYPT_MD_AlgId md_alg);

int32_t KAE_DGST_Init(KAE_DGST_Ctx* ctx, BSL_Param* param);

int32_t KAE_DGST_Update(KAE_DGST_Ctx* ctx, const uint8_t* in, uint32_t len);

int32_t KAE_DGST_Final(KAE_DGST_Ctx* ctx, uint8_t* out, uint32_t* len);

void KAE_DGST_Deinit(KAE_DGST_Ctx* ctx);

KAE_DGST_Ctx* KAE_DGST_Dup(const KAE_DGST_Ctx *src);

void KAE_DGST_Free(KAE_DGST_Ctx* ctx);

#endif